import json
from redis import ConnectionPool, StrictRedis


pool = ConnectionPool(host="localhost", port=6379, db=8)
redis = StrictRedis(connection_pool=pool, decode_responses=True)

INDEX_NAME = "user_data_index"
DATA_NAME = "user_data"
START = 0
END = 1000

# 存储值到redis
def save(data,index_name,data_name):
    for d in data:
        dump = json.dumps(d)
        try:
            pipeline=redis.pipeline()
            # 将排序的键值存储到zset  key--index_name value--username  score--age
            pipeline.zadd(index_name, {d.get("username"):d.get("age")})
            # 将内容存储到 Hash key--data_name,hkey--username value dump
            pipeline.hset(data_name, d.get("username"), dump)
            # 通过管道执行，保持原子性
            pipeline.execute()
        except Exception as e:
           return repr(e)
    return "success"



# 从redis中获取值
def get_data(index_name=INDEX_NAME,data_name=DATA_NAME,start=START,end=END,page=1,per_page=20):
    start =(page- 1) * per_page
    end_page =start+per_page-1
    # print(start,end_page,page)
    # 获取排序好的key值，返回指定范围keys
    zrange = redis.zrange(index_name, start,end_page, desc=False, withscores=True)
    # print("zrange:",zrange)
    keys = list(map(lambda x: str(x[0], encoding="utf-8"), zrange))
    # print("keys:",keys)

    #
    # 通过key值获取hash存储的数据
    data_list= []
    for key in keys:
        data = redis.hmget(data_name, key)
        data = list(map(lambda x: json.loads(str(x, encoding="utf-8")), data))
        data_list.extend(data)
    return data_list

if __name__ == "__main__":
    # 模拟生成100条用户数据
    data=[]
    for i in range(1,11):
        user= {
            "username": "zhangsan"+str(i),
            "age": i,
            "sex": "man"
        }
        data.append(user)
    # 保存数据到redis, 根据age排序, username作为key
    # 运行一次成功后可以注释掉，不再保存数据，运行下面的获取数据进行测试
    s=save(data=data,index_name=INDEX_NAME,data_name=DATA_NAME)
    print("保存数据结果:",s)

    # 模拟从redis中读取数据
    for page in range(1,2):
        # page 当前的页数,默认为1     per_page:每页读取的条数,默认为20
        u = get_data(page=page)
        print(f"读取第{page}页数据")
        print(u)
